package com.bolang.onlycode.demo.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;

public class NIOServerDu {
    public static void main(String[] args) throws IOException {
        // 创建一个选择器
        Selector selector=Selector.open();
        System.out.println(selector.getClass());
        // 创建一个通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//        ByteBuffer buffer=ByteBuffer.allocate(1024);
        // 通道监听端口
        serverSocketChannel.bind(new InetSocketAddress(7778));
        // 设置为非阻塞
        serverSocketChannel.configureBlocking(false);
        // 将通道注册到选择器上,关注
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        // 循环等待客户端连接
        while (true){
            System.out.println("正在等待客户端连接...");
            selector.select();
            //返回selector得到的结果集
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            // 使用迭代器遍历
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()){
                // 获取到selectionKey
                SelectionKey selectionKey = iterator.next();
                // 根据key对应的通道发生的事件做相应的处理
                if(selectionKey.isValid()){
                    //OP_ACCEPT,有新的客户端连接
                    if(selectionKey.isAcceptable()){
                        System.out.println("客户端已连接");
                        // 客户端生成通道
                        SocketChannel socketChannel = serverSocketChannel.accept();
                        // 通道设置为非阻塞
                        socketChannel.configureBlocking(false);
                        // 将socketChannel 注册到Selector,关注OP_READ,同时给SocketChannel关联一个Buffer
                        socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                    }
                    if(selectionKey.isReadable()){
                        System.out.println("正在从客户端读取数据");
                        // 通过selectionKey获取到对应的Channel
                        SocketChannel channel = (SocketChannel)selectionKey.channel();
                        // 获取到该channel关联的Buffer
                        ByteBuffer buffer =(ByteBuffer)selectionKey.attachment();
                        channel.read(buffer);

                        System.out.println("from Client:"+new String(buffer.array()).trim());
                        ByteBuffer buffer2 =ByteBuffer.allocate(1024);
                        System.out.println("hello client".getBytes(StandardCharsets.UTF_8).length);
                        buffer2.put("hello client".getBytes(StandardCharsets.UTF_8));
                        channel.write(buffer2);
                    }
                }
                // 从集合中移除当前的selectionKey
                iterator.remove();
            }

        }
    }

}
